package com.cbtx.tablet.service

import android.animation.Animator
import android.animation.ObjectAnimator
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.PixelFormat
import android.media.AudioAttributes
import android.media.AudioFocusRequest
import android.media.AudioManager
import android.os.Build
import android.os.Handler
import android.os.IBinder
import android.provider.Settings
import android.text.TextUtils
import android.util.Log
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.SPUtils
import com.blankj.utilcode.util.ScreenUtils
import com.cbtx.tablet.App
import com.cbtx.tablet.R
import com.cbtx.tablet.adapter.MainMenuAdapter2
import com.cbtx.tablet.bean.MainMenuBean2
import com.cbtx.tablet.constant.HttpConstant
import com.cbtx.tablet.dialog.LastTimeConfirmDialog
import com.cbtx.tablet.ui.AbsBaseActivity.Companion.REQUEST_WIFI_SET
import com.cbtx.tablet.ui.AppManager
import com.cbtx.tablet.ui.MainActivity
import com.cbtx.tablet.ui.PlayActivity
import com.cbtx.tablet.ui.StartActivity
import com.cbtx.tablet.util.DataCacheUtil
import com.cbtx.utils.FileUtil
import com.cbtx.utils.InstallApkUtil
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnItemClickListener
import com.liulishuo.filedownloader.BaseDownloadTask
import com.liulishuo.filedownloader.FileDownloadSampleListener
import com.liulishuo.filedownloader.FileDownloader
import com.liulishuo.filedownloader.util.FileDownloadUtils
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.rxkotlin.subscribeBy
import io.reactivex.schedulers.Schedulers
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
import java.util.concurrent.TimeUnit

/**
 * author : joker.peng
 * e-mail : joker@fiture.com
 * date   : 2021/7/6 11:48 PM
 * desc   :
 */
class FloatVideoWindowService : Service(), AudioManager.OnAudioFocusChangeListener {

    companion object {
        const val TAG = "FloatVideoWindowService"
    }

    private lateinit var mWindowManager: WindowManager
    private lateinit var wmParams: WindowManager.LayoutParams
    private lateinit var inflater: LayoutInflater

    //浮动布局view
    private lateinit var mFloatingLayout: View
    lateinit var mRvMenu: RecyclerView
    lateinit var container: LinearLayout
    lateinit var menuAdapter: MainMenuAdapter2
    lateinit var line: View
    lateinit var iv_hide_bg: View
    lateinit var clParent: View
    lateinit var ivHide: ImageView

    private var audioFocusRequest: AudioFocusRequest? = null
    private var audioAttributes: AudioAttributes? = null
    private var audio: AudioManager? = null

    val mMenuBeanList = mutableListOf<MainMenuBean2>()

    var mContext: Context? = null

    override fun onCreate() {
        super.onCreate()
        mContext = this
        initWindow() //设置悬浮窗基本参数（位置、宽高等）
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }


    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return super.onStartCommand(intent, flags, startId)
    }

    private fun getAppById(hotelId: Int) {
        App.sApiServiceHolder.getApiService(HttpConstant.CONTENT_ALIAS)
            .getAppId(hotelId)
            .subscribeOn(Schedulers.io())
            .unsubscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            //请求失败重连次数
            .retry(2)
            .subscribeBy(
                onError = {
                    LogUtils.e(it.toString())
                },
                onNext = {
                    mMenuBeanList.clear()
                    // 添加wifi图标
                    val mainMenuBean2 = MainMenuBean2()
                    mainMenuBean2.iconId = R.mipmap.wifi
                    mMenuBeanList.add(mainMenuBean2)

                    // 添加应用列表
                    for (i in it.data?.list?.indices!!) {
                        val bean = MainMenuBean2()
                        bean.title = it.data?.list?.get(i)!!.appName
                        bean.iconUrl = it.data?.list?.get(i)!!.appIcon
                        bean.apkUrl = it.data?.list?.get(i)!!.downloadUrl
                        bean.launchIntent = it.data?.list?.get(i)!!.packageName
                        mMenuBeanList.add(bean)
                    }
                    menuAdapter.setList(mMenuBeanList)
                    Thread{
                        DataCacheUtil.saveAppList(mMenuBeanList)
                    }.start()

                    for (i in it.data?.list?.indices!!) {
                        if (!checkIsCanGou(it.data?.list?.get(i)!!.packageName!!)) {
                            downloadApk(it.data?.list?.get(i)!!.downloadUrl!!, it.data?.list?.get(i)!!.packageName!!)
                        }
                    }
                }
            )
    }

    override fun onDestroy() {
        super.onDestroy()
        mWindowManager.removeView(mFloatingLayout)
    }

    //这是要静默安装的
    private fun downloadApk(downloadUrl: String, packageName: String) {
        if (TextUtils.isEmpty(downloadUrl)) {
            return
        }
        val indext = downloadUrl.lastIndexOf("/") + 1
        val fileName = downloadUrl.substring(indext).split("\\?".toRegex()).toTypedArray()[0]
        var path =
            FileDownloadUtils.getDefaultSaveRootPath() + File.separator + "downloadApk" + File.separator + fileName
        var baseDownloadTask = createDownLoadTask(path, downloadUrl)
        baseDownloadTask.listener = object : FileDownloadSampleListener() {
            override fun progress(task: BaseDownloadTask, soFarBytes: Int, totalBytes: Int) {
                super.progress(task, soFarBytes, totalBytes)
                Log.e("TAG", "应用安装进度：$soFarBytes--$totalBytes")
            }

            override fun error(task: BaseDownloadTask, e: Throwable) {
                super.error(task, e)
                Log.e("TAG", "异常：$e")
            }

            override fun completed(task: BaseDownloadTask) {
                super.completed(task)
                Thread {
                    InstallApkUtil.installSilent(path)
                }.start()
            }
        }
        baseDownloadTask.start()
    }

    private fun createDownLoadTask(path: String, url: String): BaseDownloadTask {
        return FileDownloader.getImpl().create(url)
            .setPath(path, false)
            .setCallbackProgressTimes(300)
            .setMinIntervalUpdateSpeed(400)
    }

    fun installApp(apkPath: String?, packageName: String?): Boolean {
        var process: Process? = null
        var successResult: BufferedReader? = null
        var errorResult: BufferedReader? = null
        val successMsg = StringBuilder()
        val errorMsg = StringBuilder()
        try {
            process = ProcessBuilder("pm", "install", "-i", packageName, "-r", apkPath).start()
            successResult = BufferedReader(InputStreamReader(process.inputStream))
            errorResult = BufferedReader(InputStreamReader(process.errorStream))
            var s: String?
            while (successResult.readLine().also { s = it } != null) {
                successMsg.append(s)
            }
            while (errorResult.readLine().also { s = it } != null) {
                errorMsg.append(s)
            }
        } catch (e: Exception) {
        } finally {
            try {
                successResult?.close()
                errorResult?.close()
            } catch (e: Exception) {
            }
            process?.destroy()
        }
        Log.e("result", "" + errorMsg.toString())
        //如果含有“success”单词则认为安装成功
        return successMsg.toString().equals("success", ignoreCase = true)
    }

    /**
     * 设置悬浮框基本参数（位置、宽高等）
     */
    private fun initWindow() {
        mWindowManager = applicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        //设置好悬浮窗的参数
        wmParams = getParams()
        // 悬浮窗默认显示以左上角为起始坐标
        wmParams.gravity = Gravity.BOTTOM
        //悬浮窗的开始位置，因为设置的是从左上角开始，所以屏幕左上角是x=0;y=0
        wmParams.y = 120
        wmParams.format = PixelFormat.TRANSLUCENT
        //得到容器，通过这个inflater来获得悬浮窗控件
        inflater = LayoutInflater.from(applicationContext)
        // 获取浮动窗口视图所在布局
        mFloatingLayout = inflater.inflate(R.layout.window_main_menu, null)
        clParent = mFloatingLayout.findViewById(R.id.cl_parent)
        line = mFloatingLayout.findViewById(R.id.v_line)
        iv_hide_bg = mFloatingLayout.findViewById(R.id.iv_hide_bg)
        container = mFloatingLayout.findViewById(R.id.container)
        mRvMenu = mFloatingLayout.findViewById(R.id.rv_menu)
        menuAdapter = MainMenuAdapter2()
        if (mRvMenu.layoutManager == null) {
            mRvMenu.layoutManager = LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false)
        }
        mRvMenu.adapter = menuAdapter

        var appList = DataCacheUtil.readAppList()
        if (appList != null) {
            menuAdapter.setList(appList)
        }

        Observable.interval(0, 300, TimeUnit.SECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                getAppById(SPUtils.getInstance().getInt("storeId"))
            }

        menuAdapter.setOnItemClickListener(object : OnItemClickListener {

            override fun onItemClick(adapter: BaseQuickAdapter<*, *>, view: View, position: Int) {

                if (position == 0) {
                    toNetSet()
                    return
                }
                val menuBean2 = adapter.data[position] as MainMenuBean2
                if (!checkIsCanGou(menuBean2.launchIntent!!)) {
                    Toast.makeText(mContext, "应用安装中，请稍后..." + menuBean2.title, Toast.LENGTH_SHORT).show()
                    return
                }
                if (menuBean2.launchIntent.equals("com.cbtx.tablet")) {
                    handler2.removeCallbacksAndMessages(null)
                    showWindowView()
                    val intent = Intent(applicationContext, MainActivity::class.java)
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    startActivity(intent)
                } else {
                    start()
                    hideWindowView()
                    val intent = packageManager.getLaunchIntentForPackage(menuBean2.launchIntent!!)
                    if (intent == null) {
                        Toast.makeText(mContext, "该应用已停止，请到系统设置-应用中启动该应用" + menuBean2.title, Toast.LENGTH_SHORT).show()
                        return
                    }
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    startActivity(intent)

                    val activity = AppManager.currentActivity()
                    if (activity is PlayActivity) {
                        activity.finish()
                    }
                }
            }
        })
        ivHide = mFloatingLayout.findViewById(R.id.iv_hide)
        ivHide.setOnClickListener(View.OnClickListener {
            if (!mIsShow) {
                showWindowView()
            } else {
                hideWindowView()
            }
        })

        // 添加悬浮窗的视图
        mWindowManager.addView(mFloatingLayout, wmParams)
    }

    fun toNetSet() {
        val netSetActivity = AppManager.currentActivity()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val panelIntent = Intent(Settings.Panel.ACTION_WIFI)
            netSetActivity?.startActivityForResult(panelIntent, REQUEST_WIFI_SET)
        } else {
            val intent = Intent()
            intent.action = "android.net.wifi.PICK_WIFI_NETWORK"
            intent.putExtra(":settings:show_fragment_as_subsetting", true)
            netSetActivity?.startActivityForResult(intent, REQUEST_WIFI_SET)
        }
    }

    /**
     * 弹出应用列表
     */
    fun showWindowView() {
        mIsShow = true
        container.visibility = View.VISIBLE
        wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT
        mWindowManager.updateViewLayout(mFloatingLayout, wmParams)
        Handler().postDelayed({
            val layoutParams = clParent.layoutParams
            layoutParams.width = 600
            clParent.layoutParams = layoutParams
            wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT
            wmParams.x = 0
            mWindowManager.updateViewLayout(mFloatingLayout, wmParams)
        }, 50)
        rotation(mIsShow)
    }

    /**
     * 隐藏应用列表
     */
    fun hideWindowView() {
        mIsShow = false
        wmParams.x = ScreenUtils.getScreenWidth()
        mWindowManager.updateViewLayout(mFloatingLayout, wmParams)
        Handler().postDelayed({
            val layoutParams = clParent.layoutParams
            layoutParams.width = 64
            clParent.layoutParams = layoutParams
            container.visibility = View.GONE
            wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT
            wmParams.x = ScreenUtils.getScreenWidth()
            mWindowManager.updateViewLayout(mFloatingLayout, wmParams)
        }, 50)
        rotation(mIsShow)
    }

    /**
     * 箭头icon旋转
     */
    private fun rotation(isShow: Boolean) {

        iv_hide_bg.setBackgroundResource(if (isShow) R.drawable.shape_window_bg_show else R.drawable.shape_window_bg_hide)

        line.visibility = if (isShow) View.VISIBLE else View.GONE
        var v1 = 0f
        var v2 = 0f
        if (isShow) {
            v1 = 180f
            v2 = 360f
        } else {
            v1 = 360f
            v2 = 180f
        }
        val anim = ObjectAnimator.ofFloat(ivHide, "rotation", v1, v2)
        anim.addListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animation: Animator) {}
            override fun onAnimationEnd(animation: Animator) {}
            override fun onAnimationCancel(animation: Animator) {}
            override fun onAnimationRepeat(animation: Animator) {}
        })
        // 动画的持续时间，执行多久？
        anim.duration = 500

        // 正式开始启动执行动画
        anim.start()
    }


    /**
     * 判断是否可以打开该应用
     */
    private fun checkIsCanGou(launchIntent: String): Boolean {
        return File("/data/data/$launchIntent").exists()
    }

    private fun getParams(): WindowManager.LayoutParams {
        wmParams = WindowManager.LayoutParams()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            wmParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
        } else {
            wmParams.type = WindowManager.LayoutParams.TYPE_PHONE
        }
        //设置可以显示在状态栏上
        wmParams.flags = (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
                or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH)

        //设置悬浮窗口长宽数据
        wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT
        wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT
        return wmParams
    }


    var isNeedBack = false

    var handler2 = Handler()

    private fun start() {
        handler2.removeCallbacksAndMessages(null)
        handler2.postDelayed({
            if (!AppUtils.isAppForeground()) {
                showCloseDialog()
            }
        }, 1000 * 60 * 30.toLong())
    }

    private fun showCloseDialog() {
        val commentConfirmDialog = LastTimeConfirmDialog(mContext!!)

        //只有这样才能弹框
        if (Build.VERSION.SDK_INT >= 26) { //8.0新特性
            commentConfirmDialog.window?.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY)
        } else {
            commentConfirmDialog.window?.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT)
        }
        commentConfirmDialog.setOnDialogListener(object : LastTimeConfirmDialog.OnDialogListener {
            override fun onCancel() {
                back()
            }

            override fun onAgree() {
                start()
                commentConfirmDialog.dismiss()
            }
        })
        if (audio == null) {
            audio = getSystemService(Context.AUDIO_SERVICE) as AudioManager
        }

        commentConfirmDialog.show()

    }

    private fun requestFocus(): Int? {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (audioFocusRequest == null) {
                if (audioAttributes == null) {
                    audioAttributes = AudioAttributes.Builder()
                        .setUsage(AudioAttributes.USAGE_MEDIA)
                        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                        .build()
                }
                audioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
                    .setAudioAttributes(audioAttributes!!)
                    .setWillPauseWhenDucked(true)
                    .setOnAudioFocusChangeListener(this)
                    .build()
            }
//            return audio?.requestAudioFocus(audioFocusRequest!!)
        }
        return null
    }

    private fun back() {
        isNeedBack = false

        //在这里实现点击重新回到Activity
        val intent = Intent(this@FloatVideoWindowService, MainActivity::class.java)
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
//        startActivity(intent)
        val pendingIntent = PendingIntent.getActivity(mFloatingLayout.context, 0, intent, 0)
        try {
            pendingIntent.send()
        } catch (e: PendingIntent.CanceledException) {
            e.printStackTrace()
        }
    }

    var mIsShow = true

    override fun onAudioFocusChange(focusChange: Int) {
        LogUtils.e("音频焦点改变")
    }
}